package com.china08.yxyapi.service.mg.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import org.apache.commons.lang.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.index.query.TermsQueryBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.GetQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import com.china08.yxyapi.entity.es.ElasticYxyQuestionBankResource;
import com.china08.yxyapi.entity.mg.huixue.YxyHuixuePlan;
import com.china08.yxyapi.entity.mg.huixue.YxyHuixuePlanKnow;
import com.china08.yxyapi.entity.mg.huixue.YxyHuixuePlanKnowTrainQues;
import com.china08.yxyapi.entity.mg.huixue.YxyHuixuePlanQues;
import com.china08.yxyapi.repository.mg.huixue.YxyHuixuePlanKnowRepository;
import com.china08.yxyapi.repository.mg.huixue.YxyHuixuePlanKnowTrainQuesRepository;
import com.china08.yxyapi.repository.mg.huixue.YxyHuixuePlanQuesRepository;
import com.china08.yxyapi.repository.mg.huixue.YxyHuixuePlanRepository;
import com.china08.yxyapi.service.mg.PlanExerciseService;

@Service
public class PlanExerciseServiceImpl implements PlanExerciseService {

    @Autowired
    private YxyHuixuePlanRepository yxyHuixuePlanRepository;

    @Autowired
    private YxyHuixuePlanKnowRepository yxyHuixuePlanKnowRepository;

    @Autowired
    private ElasticsearchTemplate et;

    @Autowired
    private YxyHuixuePlanQuesRepository yxyHuixuePlanQuesRepository;

    @Autowired
    private YxyHuixuePlanKnowTrainQuesRepository yxyHuixuePlanKnowTrainQuesRepository;

    @Autowired
    private MongoTemplate mt;

    // 出题规则 最后一级优先主观题
    private static String[][] rule = { //
            { "Aa" }, // 0
            { "Aa" }, // 1
            { "Aa" }, // 2
            { "An", "Aa" }, // 3
            { "An", "Aa" }, // 4
            { "Ba" }, // 5
            { "Ba" }, // 6
            { "Ba" }, // 7
            { "Bn", "Ba" }, // 8
            { "Bn", "Ba" }, // 9
            { "Bn", "Ba" }// 10
    };

    /**
     * 根据出题规则得到试题
     */
    @Override
    public String exerciseRule(String pkid) {
        Random rand = new Random();

        List<ElasticYxyQuestionBankResource> questionLst = new ArrayList<ElasticYxyQuestionBankResource>();

        YxyHuixuePlanKnow planKnow = yxyHuixuePlanKnowRepository.findTopByPkId(pkid);
        YxyHuixuePlan plan = yxyHuixuePlanRepository.findOne(planKnow.getPlanId());

        YxyHuixuePlanKnowTrainQues trainQues = yxyHuixuePlanKnowTrainQuesRepository
                .findOneByStudentIdAndPlanIdAndKnowIdOrderByCreatedDateDesc(plan.getStudentId(), plan.getId(),
                        planKnow.getKnowId());

        // 上次答题记录试题id
        String lastQuestId = "";
        if (trainQues != null) {
            lastQuestId = trainQues.getQuesId();
        }

        // 试题id
        String questionId = "";

        // 如果掌握度为100时 随机出题
        if (planKnow.getProgress() != 100d) {

            // 知识点星级
            Integer starsLevel = planKnow.getAttention();

            // if (starsLevel <= 1) {//
            // return null;
            // }
            String[] rules = rule[planKnow.getLevel()];
            String ruleStr = rules[0];

            // 试题难度
            String questionLevel = "";
            // 设计知识点数量
            Integer knowCount = 0;
            // 是否优先主观题
            boolean isZhu = false;

            if (planKnow.getLevel() >= 9) {
                isZhu = true;
            }
            questionLevel = ruleStr.substring(0, 1);
            switch (ruleStr.substring(1)) {
            case "a":
                knowCount = 1;
                break;
            case "n":
                knowCount = -1;
                break;
            }

            questionLst = getExercise(questionLevel, knowCount, isZhu, planKnow.getKnowId(), plan, false, false,
                    lastQuestId);
            if (questionLst.size() == 0) {
                if (rules.length > 1) {
                    ruleStr = rules[1];
                    questionLevel = ruleStr.substring(0, 1);
                    switch (ruleStr.substring(1)) {
                    case "a":
                        knowCount = 1;
                        break;
                    case "n":
                        knowCount = -1;
                        break;
                    }
                    questionLst = getExercise(questionLevel, knowCount, isZhu, planKnow.getKnowId(), plan, false, false,
                            lastQuestId);
                }
            }

            // 试题id列表
            List<String> questionIdLst = new ArrayList<String>();
            for (ElasticYxyQuestionBankResource question : questionLst) {
                questionIdLst.add(question.getId());
            }

            if (questionIdLst.size() > 0) {
                List<YxyHuixuePlanQues> planQuesLst = yxyHuixuePlanQuesRepository
                        .findByStudentIdAndPlanIdAndKnowId(plan.getStudentId(), plan.getId(), planKnow.getKnowId());
                List<String> questionIdLstTemp = new ArrayList<String>();
                questionIdLstTemp.addAll(questionIdLst);
                for (YxyHuixuePlanQues planQues : planQuesLst) {
                    if (questionIdLstTemp.contains(planQues.getQuesId())) {
                        questionIdLstTemp.remove(planQues.getQuesId());
                    }
                }
                if (questionIdLstTemp.size() > 0) { //
                    while (!StringUtils.isNotBlank(questionId)) {
                        questionId = questionIdLstTemp.get(rand.nextInt(questionIdLstTemp.size()));
                        return questionId;
                    }
                }
            }

            for (int i = 5; i >= 1; i--) {
                List<YxyHuixuePlanQues> planQuesLst = yxyHuixuePlanQuesRepository
                        .findByStudentIdAndPlanIdAndKnowIdAndWeight(plan.getStudentId(), plan.getId(),
                                planKnow.getKnowId(), i);
                for (YxyHuixuePlanQues planQues : planQuesLst) {
                    if (questionIdLst.contains(planQues.getQuesId())) {
                        if (!planQues.getQuesId().equals(lastQuestId)) {
                            questionId = planQues.getQuesId();
                            return questionId;
                        }
                    }
                }
            }

            // 初始化试题权重值
            Criteria criteria = new Criteria();
            criteria.and("student_id").is(plan.getStudentId());
            criteria.and("plan_id").is(plan.getId());
            criteria.and("know_id").is(planKnow.getKnowId());

            Query query = new Query(criteria);
            Update update = new Update();
            update.set("weight", 5);
            mt.updateFirst(query, update, YxyHuixuePlanQues.class);

            for (int i = 5; i >= 1; i--) {
                List<YxyHuixuePlanQues> planQuesLst = yxyHuixuePlanQuesRepository
                        .findByStudentIdAndPlanIdAndKnowIdAndWeight(plan.getStudentId(), plan.getId(),
                                planKnow.getKnowId(), i);
                for (YxyHuixuePlanQues planQues : planQuesLst) {
                    if (questionIdLst.contains(planQues.getQuesId())) { //
                        if (!planQues.getQuesId().equals(lastQuestId)) {
                            questionId = planQues.getQuesId();
                            return questionId;
                        }
                    }
                }
            }

            // 符合规则出随机题
            questionLst = getExercise("", 0, false, planKnow.getKnowId(), plan, true, true, lastQuestId);
            if (questionLst.size() > 0) {
                while (!StringUtils.isNotBlank(questionId)) {
                    questionId = questionLst.get(rand.nextInt(questionLst.size())).getId();
                    return questionId;
                }
            }
        }

        // 随机出题（不可重复）
        questionLst = getExercise("", 0, false, planKnow.getKnowId(), plan, true, false, lastQuestId);
        if (questionLst.size() > 0) {
            while (!StringUtils.isNotBlank(questionId)) {
                questionId = questionLst.get(rand.nextInt(questionLst.size())).getId();
                return questionId;
            }
        }

        // 随机出题（可重复）
        questionLst = getExercise("", 0, false, planKnow.getKnowId(), plan, true, false, null);
        if (questionLst.size() > 0) {
            while (!StringUtils.isNotBlank(questionId)) {
                questionId = questionLst.get(rand.nextInt(questionLst.size())).getId();
                return questionId;
            }
        }
        return null;
    }

    private List<ElasticYxyQuestionBankResource> getExercise(String questionLevel, Integer knowCount, boolean isZhu,
            String knowId, YxyHuixuePlan plan, boolean randomFlag, boolean randomZhu, String lastQuestId) {

        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();

        // 是否删除
        TermQueryBuilder builderIsDelete = new TermQueryBuilder("isDelete", 0);
        boolQueryBuilder.must(builderIsDelete);

        // 学段
        TermQueryBuilder builderStage = new TermQueryBuilder("stage", plan.getStage());
        boolQueryBuilder.must(builderStage);

        // 科目
        TermQueryBuilder builderSubject = new TermQueryBuilder("subject", plan.getSubject());
        boolQueryBuilder.must(builderSubject);

        boolQueryBuilder.mustNot(new TermsQueryBuilder("quesType", "28"));

        if (StringUtils.isNotBlank(lastQuestId)) {
            boolQueryBuilder.mustNot(new TermsQueryBuilder("id", lastQuestId));
        }

        if (!randomFlag) {
            // 难度
            String[] arrLevel = null;
            switch (questionLevel) {
            case "A":
                arrLevel = new String[] { "1", "2" };
                break;
            case "B":
                arrLevel = new String[] { "3", "4" };
                break;
            case "C":
                arrLevel = new String[] { "5" };
                break;
            }
            TermsQueryBuilder builderLevel = new TermsQueryBuilder("difficultyLevel", arrLevel);
            boolQueryBuilder.must(builderLevel);

            // 类型
            String[] arrType = { "1", "2", "3" };
            if (isZhu) {
                // 主观题
                TermsQueryBuilder builderQuesType = new TermsQueryBuilder("quesType", arrType);
                boolQueryBuilder.mustNot(builderQuesType);
            } else {
                TermsQueryBuilder builderQuesType = new TermsQueryBuilder("quesType", arrType);
                boolQueryBuilder.must(builderQuesType);
                boolQueryBuilder.mustNot(new TermsQueryBuilder("quesType", "28"));
            }

            // 知识点个数
            if (knowCount != -1) {
                TermQueryBuilder builderKnowNum = new TermQueryBuilder("knowNum", knowCount);
                boolQueryBuilder.must(builderKnowNum);
            } else {
                // 知识点数量大于2个
                RangeQueryBuilder builderKnowNum = new RangeQueryBuilder("knowNum").gt(1);
                boolQueryBuilder.must(builderKnowNum);
            }
        }
        if (randomZhu) {
            // 类型
            String[] arrType = { "1", "2", "3" };
            if (isZhu) {
                // 主观题
                TermsQueryBuilder builderQuesType = new TermsQueryBuilder("quesType", arrType);
                boolQueryBuilder.mustNot(builderQuesType);
            } else {
                TermsQueryBuilder builderQuesType = new TermsQueryBuilder("quesType", arrType);
                boolQueryBuilder.must(builderQuesType);
                boolQueryBuilder.mustNot(new TermsQueryBuilder("quesType", "28"));
            }
        }

        // 根据知识点查询(集合)
        TermsQueryBuilder builderknowOne = new TermsQueryBuilder("knowIds", knowId);
        boolQueryBuilder.must(builderknowOne);

        SearchQuery query = new NativeSearchQueryBuilder().withQuery(boolQueryBuilder).build();
        List<ElasticYxyQuestionBankResource> list = et.queryForList(query, ElasticYxyQuestionBankResource.class);

        return list;
    }

    /**
     * 根据试题id 获取试题详细信息
     * 
     * @param qid
     * @return
     */
    @Override
    public ElasticYxyQuestionBankResource getExerciseById(String qid) {

        GetQuery getQuery = new GetQuery();
        getQuery.setId(qid);
        return et.queryForObject(getQuery, ElasticYxyQuestionBankResource.class);

    }

    /**
     * 对比结果 判断是否正确
     * 
     * @param ResultTrue
     *            正确答案
     * @param ResultInput
     *            输入答案
     * @return
     */
    @Override
    public boolean correctResult(String ResultTrue, String ResultInput) {
        String[] aStrings = ResultTrue.split("");
        String[] bStrings = ResultInput.split("");

        boolean check = true;

        if (bStrings.length != aStrings.length) {
            check = false;
        } else {
            for (String a : aStrings) {
                boolean flag = false;
                for (String b : bStrings) {
                    if (a.equals(b)) {
                        flag = true;
                    }
                }
                if (!flag) {
                    check = false;
                    break;
                }
            }
        }
        return check;
    }
}
